UP | HOME

USE Flags

目录

USE flag 用于控制可选的依赖和用户可能会希望选择的设置。例如, app-editors/vim 可以可选的构建支持 ruby 解释器,并且它需要安装 dev-lang/ruby 来达成此目的 —— 我们使用 ruby USE flag 来提供这个选项。在另一方面, app-test/glark 无论什么都要求 ruby ,所以在这里没有使用 USE flag。

USE flag 的任何组合都不应导致软件包构建失败,因为用户可以设置任何组合的 flag。

软件包不应基于编译时可用的内容进行配置和链接 —— 任何自动检测都必须被覆盖。这通常指依赖项"automagic"。这很不好,因为包管理器无法间的到该依赖,并且很容易破坏依赖和一些其他的问题。

automagic 依赖最好通过准备构建系统 patch 来修复,其 patch 添加适当的选项来控制有疑问的依赖,并且提交该 patch 到上游让所有用户收益。为避免在下游携带附加的补丁,通常可以使用特殊的构建系统选项来解决(例如在 autotools 中缓存变量)或无条件的依赖相关软件包来解决 automagic 依赖(即强制检查总是成功)。

Note: USE flag 的状态保存在 VDB 中,并且它们在 pkg_prermpkg_postrm 中的值从这里获取。这意味着在 merge 和 unmerge 之间设置或取消设置 USE flag 是无效的。

When not to use USE flags?

尽管通常认为 USE flag 对用户有利,但也有一些避免使用它们的有效用例。当写 ebuild 时的,考虑是否为一个特定功能添加 flag,或探索以下描述的替代方案之一。

当软件包未链接时, USE flag 的使用不应该控制运行时依赖。这样做会未软件包创建额外的配置,并重新编译磁盘上没有更改的底层文件。这应该避免这种情况,改为如果有需要则通过安装后的消息传达给用户。

USE flag 不得用于控制小型、非侵入式、不会引入其他构建时依赖或导致构建时间显著增加的文件。例如此类文件包括 bash 补全文件,init.d 脚本,logrotate 配置文件,systemd 服务文件。基本原理与上述相同。这些文件必须无条件的安装。

对于具有多个条件程序或模块的包,可以进行类似的处理。每当这会导致大量的 USE flag,迫使用户花费大量的时间选择兼容的 flag,并可能在不完整的选择后重新构建,考虑减少将 flag 用于那些具有外部依赖和/或构建时间较长的程序或模块。剩余的部分应该改为无条件构建,或由像 minimal 的 flag 控制。

你不应该引入仅用于操作 CFLAGSFEATRUES 等类似由用户直接配置的变量的 USE flag。反而,软件包应避免操作它们,并让用户直接设置它们。常见的错误包括:

  1. 使用 debug USE flag 来强制 -O0 -g 并禁用 stripping。 debug flag 的正确目的应该是控制附加的调试代码路径。用户应该负责使用正确的 flags 和特性来保留调试信息。
  2. 引入 lto flag 并强制 -flto 。这是用户应该直接在 flag 变量设置的。
  3. 使用 CPU_FLAGS_* 来控制 -m* 选项。这些 flag 旨在显式控制要求特定 CPU 扩展的代码路径,例如 separate assembly。编译器生成的程序集应尊重用户的 -march 选择。

在某些极端情况下,这些规则可能不适用。例如,一些上游要求用户使用特定的 CFLAGS 并且拒绝使用其他值构建的错误报告。在这种情况,默认情况下会 strip flag 并提供 custom-cflags flag,以允许用户强制使用其首选 flag。

noblah USE Flags

避免 noblah 风格的 use flag。它们会破坏 use.mask 并且对架构开发者造成各种复杂问题。原因如下:

考虑一个名为'vplayer'的假想包,其功能为播放视频。该软件包通过 USE flag 对各种声音和视频输出方法、各种视频解码等提供可选支持。

vplayer 的可选功能之一是提供对'fakemdia'的解码支持,不幸的是它仅以狡猾的 x86 二进制形式提供。我们通过执行嗯以下操作来解决此问题:

RDEPEND="x86? ( fakemdia? ( >=media-libs/fakemdia-1.1 ) )"

除了这种方法非常肮脏 —— 当 AMD64 二进制文件也这样做会发生什么?还有,在其他架构的用户会在 emerge -pv 输出中看到列出的 fakemdia,即使它实际上不可用。

类似的,假如 vplayer 将支持通过 ALSA 解码器输出作为一个选项。然而 ALSA 在 SPARC 或 Alpha 上不可用(或在编写此示例时)。所以我们可以这样做:

DEPEND="!sparc? ( !alpha? ( alsa? ( media-libs/alsa-lib ) ) )"

同样,这很混乱,并且 ALSA 同样会出现在 emerge -p 的输出中。而且,一旦 ALSA 开始在 SPARC 上工作时,每一个这么做的 ebuild 都必须手动编辑。

解决办法是 use.mask ,该文件记录在Profile use.make文件中。每个 profile 都可以有一个 use.mask 文件,该文件用于强制禁用给定架构(或子架构,或 subprofile)上的特定 USE flag。所以,如果 fakemdia USE flag 在每一个非 x86 pofile 的 use.mask 中,以下内容完全合法并且不会破坏任何内容:

RDEPEND="fakemedia? ( >=media-libs/fakemedia-1-1 )"

非 x86 的用户在执行 emerge -pv vplayer 时会看到以下内容:

[ebuild R ] media-video/vplayer-1.2 alsa -blah (-fakemedia) xyz

要向 use.mask 添加一个 flag,请询问相关的架构团队。

IUSE defaults

IUSE 中 use flag 的名称前添加 +- 以默认将其打开或关闭。

Important:在 IUSE 中添加 - 到 flag 之前时非常没有用的,因为它既不会覆盖用户的配置(make.conf),也不会覆盖 profile 默认(make.defualts=和=package.use)。有关 Portage 中 USE 顺序的详细信息,请参见 amke.conf(5)。

Local and Global USE Flags

USE flag 可分为本地或全局。一个全局 USE flag 必须满足几个标准:

  • 它被许多不同的软件包使用,至少 5 个似乎满足以上条件。
  • 它具有一般的非特定用途。

第二点非常重要。如果 USE flag 对 pkg-one 于对 pkg-two 的影响大不相同,那么该表示不是成为全局 flag 的合适候选者。尤其要注意,如果曾经引入 clientserver USE flag,则由于这个原因它们不能成为全局 USE flag。

在引入一个新的全局 USE flag 之前, 它必须在 gentoo-dev 邮件列表中进行讨论。

USE Flag Descriptions

必须在 profile/ 目录的 use.desc 或软件包目录的 metadata.xml 中描述所有 USE flag。见 man portage 或这些文件中的注释以获取格式说明。 记得保持这些文件的排序。 use.local.desc 文件自动从软件包的 metadata.xml 生成的,并且可以由解析树的工具使用。因为 use.local.desc 是自动生成的,因此绝对不能在树中进行手动编辑。更多信息见GLEP 56

USE_EXPAND flag 是一个例外,其必须记录在 profile/desc/ 目录中。每个 USE_EXPAND 变量需要一个文件,该文件必须包含该变量可以采用的可能的值的说明。格式见这些文件中的注释,并且记住保持这些文件的排序。

Conflicting USE Flags

偶尔 ebuild 的 USE 会因为功能性产生冲突。检查它们并返回一个错误不是一个可行的方法。相反,你必须在冲突中选择一个青睐的 USE flag,并应警告用户使用了特定的 flag。

一个示例来自 mail-mta/mstmp ebuild。软件包可以使用代 GnuTLS 的 SSL,代 OpenSSL 的 SSL 或者完全不使用 SSL。因为 GnuTLS 比 OpenSSL 具有更多功能,因此受到青睐:

    src_compile() {
        local myconf

        if use ssl && use gnutls ; then
        myconf="${myconf} --enable-ssl --with-ssl=gnutls"
        elif use ssl && ! use gnutls ; then
        myconf="${myconf} --enable-ssl --with-ssl=openssl"
        else
            myconf="${myconf} --disable-ssl"
        fi

        econf \
        # Other stuff
        ${myconf}

        emake
    }

在某些特殊情况下,上述策略会破坏反向 USE 依赖。为了避免如此,ebuild 可以使用 REQUIRED_USE 指定允许的 USE flag 组合。关于其语法的描述请见REQUIRED_USE章节。

例如,如果一个软件包 dev-libs/foo 可以使用 USE="a"USE="b" 之一构建,但不是同时使用,那么首选其中一个 flag 将破坏依赖于 dev-libs/foo[a]dev-libs/foo[b] 的软件包。因此在这种情况中,ebuild 应该指定 REQUIRED_USE="a ? ( !b )"

NOTE: 为了避免迫使用户过多的 micro-manage falg,应谨慎的使用 REQUIRED_USE 。只要有可能进行满足用户需求的构建,就应遵循常规策略。

USE_EXPAND and ARCH USE Flags

VIDEO_CARDSINPUT_DEVICESL10N 变量会自动扩展为 USE flag。这些称为 USE_EXPAND 变量。例如,如果用户在 make.conf 中有 L10N="en fr" ,那么 USE="l10n_en l10n_fr" 会自动被 portage 设置。会自动被 portage 设置。会自动被 portage 设置。会自动被 portage 设置。

自 Prtage 2.0.51.20 其, USE_EXPAND 列表被设置在 profile/bas/make.defaults 中。未经过 gentoo-dev 列表的讨论,不能对其进行修改,并且在任何 subprofile 中也不能对其修改。

当前架构(例如, x86sparcppc-macos )会被自动设置为 USE flag。有关有效的有关架构关键词的完整列表,请见 profile/arch.listGLEP 22对其格式进行了说明。

Warning:架构变量与 ACCEPT_KEYWORDS 有某种联系是一个常见的误解。它们没有联系。例如,在 sparc 上接受 x86 关键字,并不会设置 USE\"x86" 。类似的,也没有 ~arch USE flag,所以不要尝试 if use ~x86

作者: Petrus.Z

Created: 2021-09-01 Wed 00:38